#include "xmppmanager.h"
#include "xmpp.h"
#include <QCoreApplication>
#include <QWaitCondition>
#include <QMutex>
#include <iostream>

int EVENT_LOGIN;
int EVENT_LOGOFF;
int EVENT_CONTACT_INFO;
int EVENT_CONTACT_INFOS;
int EVENT_MESSAGE_RECEIVED;
int EVENT_MESSAGE_SESSION;


XmppManager::XmppManager()
{
   EVENT_LOGIN = QEvent::registerEventType ();
   EVENT_LOGOFF = QEvent::registerEventType ();
   EVENT_CONTACT_INFO = QEvent::registerEventType ();
   EVENT_CONTACT_INFOS = QEvent::registerEventType ();
   EVENT_MESSAGE_RECEIVED = QEvent::registerEventType ();
   EVENT_MESSAGE_SESSION = QEvent::registerEventType ();
}

void XmppManager::run()
{
    std::clog << "XmppThread started..." << std::endl;
    Xmpp::instance().connect();
    std::clog << "XmppThread ended..." << std::endl;
}

bool XmppManager::login(QString& id, QString& password)
{
    m_strId = id;
    m_strPassword = password;
    Xmpp::instance().setLoginInfo(m_strId.toStdString(), m_strPassword.toStdString());
    Xmpp::instance().setDelegate(this);
    start();
    return true;
}

void XmppManager::logout()
{
    Xmpp::instance().disconnect();
    wait();
}

gloox::MessageSession* XmppManager::createSession(std::string& jid)
{
    return Xmpp::instance().startChat(jid);
}

void XmppManager::closeSession(gloox::MessageSession* session)
{
    Xmpp::instance().closeSession(session);
}

bool XmppManager::requestVcard(QString& jid)
{
    if (!Xmpp::instance().isConnected())
        return false;
    Xmpp::instance().requestVcard(jid.toStdString());
    return true;
}

void XmppManager::onConnect()
{
    for (std::list<QObject*>::iterator it = m_LoginHandlers.begin();
    it != m_LoginHandlers.end(); it++) {
        QCoreApplication::postEvent(*it, new QEvent((QEvent::Type)EVENT_LOGIN));
    }
}


void XmppManager::onDisconnect(int const error)
{
    for (std::list<QObject*>::iterator it = m_LoginHandlers.begin();
    it != m_LoginHandlers.end(); it++) {
        LogoffEvent * event = new LogoffEvent(error);
        QCoreApplication::postEvent(*it, event);
    }
}

void XmppManager::onContactItem(ContactItem& item)
{
    ContactEvent* event;
    for (std::list<QObject*>::iterator it = m_ContactHandlers.begin();
    it != m_ContactHandlers.end(); it++) {
        event = new ContactEvent((QEvent::Type)EVENT_CONTACT_INFO);
        event->contact = item;
        QCoreApplication::postEvent(*it, event);
    }
}

void XmppManager::onContactItems(std::vector<ContactItem>& items)
{
    ContactsEvent* event;
    for (std::list<QObject*>::iterator it = m_ContactHandlers.begin();
    it != m_ContactHandlers.end(); it++) {
        event = new ContactsEvent(items);
        QCoreApplication::postEvent(*it, event);
    }

}

void XmppManager::onMessageSession(gloox::MessageSession *session)
{
    MessageSessionEvent* event;
    for (std::list<QObject*>::iterator it = m_MessageSessionHandlers.begin();
    it != m_MessageSessionHandlers.end(); it++) {
        QMutex mutex;
        mutex.lock();
        QWaitCondition condition;
        event = new MessageSessionEvent(session, condition);
        QCoreApplication::postEvent(*it, event);
        condition.wait(&mutex);
        mutex.unlock();
    }
}
